import threading
import time

# 用于线程安全的输出
print_lock = threading.Lock()


# 模拟获取当前时间（基于一个开始时间点）
def get_current_time(start):
    return int(time.time() - start)


# 模拟获取从开始到现在的经过时间
def get_elapsed_time(start):
    return get_current_time(start)


Bmutex = threading.Semaphore(0)
Dmutex = threading.Semaphore(0)

flag = False  # 是否有一方已经下班


# 司机进程
def driver(start, start_sleep, maxTime):
    time.sleep(start_sleep)
    with print_lock:
        print(f'时间点  {get_current_time(start)}  司机 开始工作')
    global flag
    while True:
        Bmutex.acquire()  # 请求发车
        with print_lock:
            print(f'时间点  {get_current_time(start)}  司机  启动车辆')
        time.sleep(3)
        with print_lock:
            print(f'时间点  {get_current_time(start)}  司机  正常行驶')
        time.sleep(3)
        with print_lock:
            print(f'时间点  {get_current_time(start)}  司机  到站停车并通知售票员开门')
        time.sleep(3)
        Dmutex.release()  # 允许开门

        # 检查是否应该下班
        if flag or get_elapsed_time(start) >= maxTime:
            with print_lock:
                print(f'时间点  {get_current_time(start)}  司机  下班')
            flag = True  # 设置标志，确保另一个线程也能看到
            break


# 售票员进程
def ticketSeller(start, start_sleep, maxTime):
    time.sleep(start_sleep)
    with print_lock:
        print(f'时间点  {get_current_time(start)}  售票员  开始工作')
    global flag
    while True:
        with print_lock:
            print(f'时间点  {get_current_time(start)}  售票员  让乘客上车')
        time.sleep(3)
        with print_lock:
            print(f'时间点  {get_current_time(start)}  售票员  关闭车门并通知司机启动')
        time.sleep(3)
        Bmutex.release()  # 允许发车
        with print_lock:
            print(f'时间点  {get_current_time(start)}  售票员  进行售票')
        time.sleep(3)
        Dmutex.acquire()  # 请求开门
        with print_lock:
            print(f'时间点  {get_current_time(start)}  售票员  打开车门让乘客下车')
        time.sleep(3)
        # 检查是否应该下班
        if flag or get_elapsed_time(start) >= maxTime:
            with print_lock:
                print(f'时间点  {get_current_time(start)}  售票员  下班')
            flag = True
            break



def get_positive_integer(prompt):
    while True:
        try:
            value = int(input(prompt))
            if value >= 0:
                return value
            else:
                print("输入无效，请输入一个非负整数。")
        except ValueError:
            print("输入无效，请输入一个非负整数。")

# 主程序
if __name__ == "__main__":
    start_time_driver = get_positive_integer("请输入司机开始上班时间: ")
    end_time_driver = get_positive_integer("请输入司机下班时间: ")
    start_time_conductor = get_positive_integer("请输入售票员开始上班时间: ")
    end_time_conductor = get_positive_integer("请输入售票员下班时间: ")

    start_time = time.time()
    t1 = threading.Thread(target=driver, args=(start_time, start_time_driver, end_time_driver))
    t2 = threading.Thread(target=ticketSeller, args=(start_time, start_time_conductor, end_time_conductor))

    t1.start()
    t2.start()

    t1.join()
    t2.join()
    print("所有任务已完成。")
